// 缓存管理工具
export interface CacheItem<T> {
    data: T
    timestamp: number
    ttl: number
    accessCount: number
    lastAccessed: number
}

export class CacheManager<T = any> {
    private cache = new Map<string, CacheItem<T>>()
    private maxSize: number
    private defaultTTL: number
    private cleanupInterval: NodeJS.Timeout | null = null

    constructor(maxSize = 100, defaultTTL = 5 * 60 * 1000) { // 默认5分钟TTL
        this.maxSize = maxSize
        this.defaultTTL = defaultTTL
        this.startCleanup()
    }

    // 设置缓存项
    set(key: string, data: T, ttl?: number): void {
        const now = Date.now()
        const item: CacheItem<T> = {
            data,
            timestamp: now,
            ttl: ttl || this.defaultTTL,
            accessCount: 0,
            lastAccessed: now
        }

        // 如果缓存已满，删除最少使用的项
        if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
            this.evictLRU()
        }

        this.cache.set(key, item)
    }

    // 获取缓存项
    get(key: string): T | null {
        const item = this.cache.get(key)
        if (!item) return null

        const now = Date.now()

        // 检查是否过期
        if (now - item.timestamp > item.ttl) {
            this.cache.delete(key)
            return null
        }

        // 更新访问统计
        item.accessCount++
        item.lastAccessed = now

        return item.data
    }

    // 检查缓存是否存在且有效
    has(key: string): boolean {
        return this.get(key) !== null
    }

    // 删除缓存项
    delete(key: string): boolean {
        return this.cache.delete(key)
    }

    // 清空缓存
    clear(): void {
        this.cache.clear()
    }

    // 获取缓存统计
    getStats() {
        const now = Date.now()
        let validItems = 0
        let expiredItems = 0
        let totalSize = 0

        for (const [key, item] of this.cache) {
            if (now - item.timestamp > item.ttl) {
                expiredItems++
            } else {
                validItems++
            }
            totalSize += this.estimateSize(item.data)
        }

        return {
            totalItems: this.cache.size,
            validItems,
            expiredItems,
            maxSize: this.maxSize,
            estimatedSize: totalSize,
            hitRate: this.calculateHitRate()
        }
    }

    // LRU淘汰策略
    private evictLRU(): void {
        let lruKey: string | null = null
        let lruTime = Date.now()

        for (const [key, item] of this.cache) {
            if (item.lastAccessed < lruTime) {
                lruTime = item.lastAccessed
                lruKey = key
            }
        }

        if (lruKey) {
            this.cache.delete(lruKey)
        }
    }

    // 估算数据大小
    private estimateSize(data: any): number {
        try {
            return JSON.stringify(data).length * 2 // 粗略估算
        } catch {
            return 0
        }
    }

    // 计算命中率
    private calculateHitRate(): number {
        let totalAccess = 0
        for (const item of this.cache.values()) {
            totalAccess += item.accessCount
        }
        return totalAccess > 0 ? (this.cache.size / totalAccess) * 100 : 0
    }

    // 定期清理过期项
    private startCleanup(): void {
        this.cleanupInterval = setInterval(() => {
            const now = Date.now()
            for (const [key, item] of this.cache) {
                if (now - item.timestamp > item.ttl) {
                    this.cache.delete(key)
                }
            }
        }, 60000) // 每分钟清理一次
    }

    // 停止清理
    destroy(): void {
        if (this.cleanupInterval) {
            clearInterval(this.cleanupInterval)
            this.cleanupInterval = null
        }
        this.clear()
    }
}

// 全局缓存实例
export const globalCache = new CacheManager()

// API响应缓存装饰器
export function cacheResponse(ttl?: number) {
    return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
        const method = descriptor.value
        descriptor.value = async function (...args: any[]) {
            const cacheKey = `${propertyName}_${JSON.stringify(args)}`

            // 尝试从缓存获取
            const cached = globalCache.get(cacheKey)
            if (cached) {
                return cached
            }

            // 执行原方法
            const result = await method.apply(this, args)

            // 缓存结果
            globalCache.set(cacheKey, result, ttl)

            return result
        }
    }
}

// React Hook for cache management
export function useCache<T>(key: string, fetcher: () => Promise<T>, ttl?: number) {
    const getCachedData = (): T | null => {
        return globalCache.get(key)
    }

    const setCachedData = (data: T): void => {
        globalCache.set(key, data, ttl)
    }

    const invalidateCache = (): void => {
        globalCache.delete(key)
    }

    return {
        getCachedData,
        setCachedData,
        invalidateCache
    }
}

// 图像缓存管理
export class ImageCacheManager extends CacheManager<string> {
    constructor() {
        super(50, 10 * 60 * 1000) // 50张图片，10分钟TTL
    }

    // 预加载图像
    async preloadImage(url: string): Promise<string> {
        if (this.has(url)) {
            return this.get(url)!
        }

        return new Promise((resolve, reject) => {
            const img = new Image()
            img.onload = () => {
                // 将图像转换为base64缓存
                const canvas = document.createElement('canvas')
                const ctx = canvas.getContext('2d')!
                canvas.width = img.width
                canvas.height = img.height
                ctx.drawImage(img, 0, 0)
                const dataUrl = canvas.toDataURL()

                this.set(url, dataUrl)
                resolve(dataUrl)
            }
            img.onerror = reject
            img.src = url
        })
    }

    // 批量预加载
    async preloadImages(urls: string[]): Promise<void> {
        const promises = urls.map(url => this.preloadImage(url).catch(() => null))
        await Promise.allSettled(promises)
    }
}

export const imageCache = new ImageCacheManager()